"""
Copyright (c) 2023 - present SKbioinfo
"""
import os,json
from flask_restful import Resource
from flask import request,jsonify,current_app
from apps.API.utils.log_helper import lg
from flask_jwt_extended import jwt_required
from apps.API.reportCreator.model import reportRecord
from apps.API.pipeExecutor.models import Analysis
from docxtpl import DocxTemplate
from datetime import datetime
import pandas as pd
from apps import db

class interfaceCreateReport(Resource):
    
    def __init__(self):
        self.organ={'AD':'脂肪','BM':'骨髓','DP':'牙髓','HF':'毛囊','PL':'胎盘','UC':'脐带'}
    
    def _extract_quality_check(self,data):## 需要确认第三行的判定标准
        # 获取最小均值质量
        read1_means = data["read1_after_filtering"]["quality_curves"]["mean"]
        read2_means = data["read2_after_filtering"]["quality_curves"]["mean"]
        min_read1 = min(read1_means)
        min_read2 = min(read2_means)
        return "合格" if min_read1 > 20 and min_read2 > 20 else "不合格"
    
    def _parse_qc(self,json_path, sample_id, prefix):
        with open(json_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
            raw_q30 = data["summary"]["before_filtering"]["q30_rate"]
            raw_q30_percent = f"{raw_q30 * 100:.2f}%"
            clean_bases = data["summary"]["after_filtering"]["total_bases"]
            clean_gb = f"{clean_bases / 1e9:.2f}Gb"
            base_quality = self._extract_quality_check(data)
            is_pass = raw_q30 * 100 > 90 and (clean_bases / 1e9) > 5 and base_quality == "合格"
            return {
                f"sample_id_{prefix}": sample_id,
                f"q30_rate_{prefix}": raw_q30_percent,
                f"clean_base_{prefix}": clean_gb,
                f"base_quality_{prefix}": base_quality,
                f"pass_check_{prefix}": "☑" if is_pass else "☐",
                f"fail_check_{prefix}": "☐" if is_pass else "☑"
            }

    @jwt_required()
    def post(self,run_id):
        try:
            base_dir=current_app.config.get("BASE_DIR")
            run_id=request.json['form']["run_id"]
            time_dir=request.json['rowData']['run_create_time'].split()[0]
            base_dir_path=f'{base_dir}/results/{time_dir}/{run_id}'
            # # tpm数据
            tpm = pd.read_csv(f"{base_dir_path}/AllSample_TPM_21gene.csv", header=0, encoding='utf-8')
            # # 预测结果 result
            result = pd.read_csv(f"{base_dir_path}/result.csv", header=0, encoding='utf-8')
            organ = self.organ
            result['PredTIS'] = result['PredTIS'].replace(organ)
            # 对数值类型的列保留三位小数
            result = result.applymap(lambda x: f"{x:.3f}" if isinstance(x, (int, float)) else x)
            # 转换为字典，方便word模板遍历读入
            result = result.to_dict(orient='records')
            # 信息填写
            sample_name = request.json["form"]["sample_name"]
            batch_no = request.json["form"]["batch_no"]
            manufacturer = request.json["form"]["manufacturer"]
            sample_id = request.json["form"]["sample_id"]
            quality_std = request.json["form"]["quality_std"]
            culture_medium = request.json["form"]["culture_medium"]
            trizol = request.json["form"]["Trizol"]
            seq_provider = request.json["form"]["seq_provider"]
            seq_conditions = request.json["form"]["seq_condition"]
            raw_data_path = request.json["form"]["raw_data_path"]
            ######################################3.加载模板###########################################
            report_template_prefix=current_app.config.get("REPORT_PATH")
            report=request.json["form"]["report_template"]
            report_template_path=f'{report_template_prefix}/{report}'
            doc = DocxTemplate(report_template_path)
            context = {
                'sample_name': sample_name,
                'batch_no': batch_no,
                'manufacturer': manufacturer,
                'sample_id': sample_id,
                'quality_std': quality_std,
                'culture_medium': culture_medium,
                'trizol': trizol,
                'seq_provider': seq_provider,
                'seq_conditions': seq_conditions,
                'raw_data_path': raw_data_path,
                'result':result
            }
            # 样品名称
            sample_names=request.json['form']['select_sample'].replace(' ','').split('|')[1].split('&')
            sample1=sample_names[0]
            sample2=sample_names[1]
            # 分析样本1数据
            sample1_context = self._parse_qc(f'{base_dir_path}/{sample1}.json', sample1, "1")
            # 分析样本2数据
            sample2_context = self._parse_qc(f'{base_dir_path}/{sample2}.json', sample2, "2")
            # 合并到主 context 中（会覆盖同名键，但此处前缀不同不会冲突）
            context.update(sample1_context)
            context.update(sample2_context)
            # # 渲染文档
            doc.render(context)
            # 提取样本tpm数据，导出附件
            timestamp = datetime.now().strftime('%Y%m%d%H%M%S%f')
            os.makedirs(f'{base_dir_path}/{timestamp}',exist_ok=True)
            # tpm_sample = tpm[['Gene.ID', 'Gene.Name', 'Reference', 'Strand', 'Start', 'End']]
            # result_sample = result[result['ID'].str.contains(combine_name)]
            # tpm_sample.to_csv('/mnt/e/work/research/script/RNAseq/SK_RNAseq/word/附件3_AllSample_TPM_21gene.csv')
            # result_sample.to_csv('/mnt/e/work/research/script/RNAseq/SK_RNAseq/word/附件4_result.csv')
            # 替换result 中 PredTIS列中的值
            ana=Analysis.query.filter(Analysis.run_id==run_id).first()
            run_at=str(ana.to_dict()["run_create_time"]).split()[0]
            newReport=reportRecord(
                run_id=run_id,
                sample_1=sample1,
                sample_2=sample2,
                reportTmp=report,
                timestamp=timestamp,
                run_at=run_at
            )
            db.session.add(newReport)
            db.session.commit()
            doc.save(f'{base_dir_path}/{timestamp}/{timestamp}.docx')
            response=jsonify({"report":f'样品:{sample1}_{sample2}报告'})
            response.status=202
            return response
        except Exception as e:
            lg.error(e)
            response=jsonify({"error":str(e) + "出现错误，请重新生成报告！"})
            response.status=404
            return response
